﻿using Module.Common.Common.QiPuHelper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceItem.Engine
{
    /// <summary>
    /// 着法存储类，用于存储UCCI的单行解析信息
    /// </summary>
    internal class UcciInfoLine
    {
        internal int Depth { get; set; }
        internal int Score { get; set; }
        internal List<string> UcciStrList { get; set; } // 着法列表，Ucci格式
        internal List<string> CnStrList { get; set; } // 着法列表，中文格式
        public StepData FirstStep { get; set; }
        private string _InfoLineStr;
        internal string InfoLineStr  // 象棋引擎返回的原始信息，按行分隔，
        {
            get { return _InfoLineStr; }
            set
            {
                _InfoLineStr = value.Trim();
                UcciStrList.Clear();
                Depth = 0;
                Score = 0;
                if (!_InfoLineStr.Contains("info depth"))
                {
                    return;
                }
                string[] strarr = _InfoLineStr.Split(" ");
                Depth = int.Parse(strarr[Array.IndexOf(strarr, "depth") + 1]); // 搜索深度
                Score = int.Parse(strarr[Array.IndexOf(strarr, "score") + 1]); // 分值
                int start = Array.IndexOf(strarr, "pv") + 1; // “pv”后边是着法，着法可能仅有一个，也可能是一串。
                for (int i = start; i < strarr.Length; i++)
                {
                    UcciStrList.Add(strarr[i].Trim());
                }
                //FirstStep = GetStep(UcciStrList[0], GlobalValue.QiPan);
                
            }
        }
        /// <summary>
        /// 类初始化
        /// </summary>
        public UcciInfoLine()
        {
            UcciStrList = new List<string>();
            CnStrList = new List<string>();
        }
        /// <summary>
        /// 获取着法信息串
        /// </summary>
        /// <returns></returns>
        internal string GetMove(in int[,] QiPan)
        {
            string movestr = "";
            CnStrList.Clear();
            CnStrList = UcciStrToCnStr(UcciStrList, QiPan);
            if (CnStrList.Count > 0)
            {
                foreach (string str in CnStrList)
                {
                    movestr += str + " ";
                }
            }
            else
            {
                movestr = "无";
            }
            return movestr;
        }
        

        /// <summary>
        /// 将单个UCCI着法指令，转换为中文着法指令
        /// </summary>
        /// <param name="fenStr">UCCI着法指令，例如"h9g8"</param>
        /// <param name="curQiPan">棋盘数据数组</param>
        /// <returns>中文着法指令,例如“马八进七”</returns>
        private List<string> UcciStrToCnStr(List<string> strlist, int[,] curQiPan)
        {
            int[,] qipan = new int[9, 10];
            for (int i = 0; i <= 8; i++)
            {
                for (int j = 0; j <= 9; j++)
                {
                    qipan[i, j] = curQiPan[i, j];
                }
            }

            List<string> resultlist = new();
            foreach (string str in strlist)
            {
                string workStr = UcciStrToCnStr(str, qipan, true);
                resultlist.Add(workStr);
            }
            return resultlist;
        }

        /// <summary>
        /// 将单个UCCI着法，转换为中文着法
        /// </summary>
        /// <param name="ucciStr">UCCI着法</param>
        /// <param name="qipan">棋盘数据</param>
        /// <param name="writeQipan">是否有后续着法，用于避免改动系统现棋盘数据，导致数据错误</param>
        /// <returns></returns>
        private string UcciStrToCnStr(string ucciStr, int[,] qipan, bool writeQipan)
        {
            ucciStr = ucciStr.Trim();
            if (ucciStr.Length != 4)
            {
                return "";
            }
            string cols = "abcdefghi";
            string rows = "9876543210";
            int x0 = cols.IndexOf(ucciStr[0]);  // 现位置
            int y0 = rows.IndexOf(ucciStr[1]);
            int x1 = cols.IndexOf(ucciStr[2]);  // 目标位置
            int y1 = rows.IndexOf(ucciStr[3]);
            string resultstr = "";
            int qizi = qipan[x0, y0];
            if (qizi > -1)
            {
                resultstr = TranslateToCN(qizi, x0, y0, x1, y1);
                //if (qizi < 16) resultstr += System.Environment.NewLine;
                if (writeQipan)
                {
                    qipan[x0, y0] = -1;
                    qipan[x1, y1] = qizi;
                }
            }
            return resultstr;
        }

        /// <summary>
        /// 棋子的中文简称，用于棋谱翻译
        /// </summary>
        private readonly string[] qiZiCnName = {
            "将", "士", "士", "象", "象", "马", "马", "车", "车", "炮", "炮", "卒", "卒", "卒", "卒", "卒",
            "帅", "仕", "仕", "相", "相", "马", "马", "车", "车", "炮", "炮", "兵", "兵", "兵", "兵", "兵"
        };
        private readonly string[] CnNumber = { "", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        /// <summary>
        /// 转换为中文走棋指令
        /// </summary>
        /// <param name="QiZi"></param>
        /// <param name="x0"></param>
        /// <param name="y0"></param>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <returns></returns>
        public string TranslateToCN(int QiZi, int x0, int y0, int x1, int y1)
        {
            string char1 = qiZiCnName[QiZi];
            string char2 = QiZi is >= 0 and <= 15 ? (x0 + 1).ToString() : CnNumber[9 - x0];
            string char3 = "";
            string char4;
            #region 棋谱翻译为中文
            int m = Math.Abs(y1 - y0);
            // 进退平
            if (y0 == y1)
            {
                char3 = "平";
                char4 = QiZi is >= 0 and <= 15 ? (x1 + 1).ToString() : CnNumber[9 - x1];
            }
            else
            {
                if (QiZi is >= 0 and <= 15)
                {
                    char3 = y1 > y0 ? "进" : "退";
                }
                if (QiZi is >= 16 and <= 31)
                {
                    char3 = y1 > y0 ? "退" : "进";
                }

                char4 = QiZi switch
                {
                    1 or 2 or 3 or 4 or 5 or 6 => (x1 + 1).ToString(),
                    17 or 18 or 19 or 20 or 21 or 22 => CnNumber[9 - x1],
                    // 其他所有可以直走的棋子
                    _ => QiZi is >= 0 and <= 15 ? m.ToString() : CnNumber[m],
                };

            }
            #endregion
            return char1 + char2 + char3 + char4;
        }
        
        /// <summary>
        /// 获取着法的原位置和目标位置坐标数据，用于电脑走棋和箭头提示
        /// </summary>
        /// <returns></returns>
        public List<System.Drawing.Point> GetPoint()
        {
            List<System.Drawing.Point> points = new();
            System.Drawing.Point pt0 = new(FirstStep.X0, FirstStep.Y0);
            points.Add(pt0);
            System.Drawing.Point pt1 = new(FirstStep.X1, FirstStep.Y1);
            points.Add(pt1);
            return points;
        }
    }
}
